const charset = require('superagent-charset');
const superagent =  charset(require('superagent'));
require('superagent-proxy')(superagent);
const fs = require('fs');
const { Console } = require('console');
const { exit } = require('process');

const {
    get,
    easyPushWechatMsg,
    lpush,
    set,
    hget,
    hset,
    expire,
    hgetall,
    randBetween,
    avoidNoticeFreq,
    avoidNoticeFreqCookie,
} = require('./util');

const fetchTask = 'http://wafer.shenzhenbenwo.com/api/Tiserial/fetch';

//console信息输出到文件
const output = fs.createWriteStream('./stdout.log');
const errOutput = fs.createWriteStream('./stderr.log');
const consoleLogger = new Console({stdout: output, stderr: errOutput});

const sleep = ms => {
	return new Promise(resolve => setTimeout(resolve, ms));
}
const logger = function() {
	console.log('[', (new Date()).Format("yyyy-MM-dd hh:mm:ss"), ']', ...arguments);
	consoleLogger.log('[', (new Date()).Format("yyyy-MM-dd hh:mm:ss"), ']', ...arguments);
	return null;
}


// 对Date的扩展，将 Date 转化为指定格式的String
// 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符，
// 年(y)可以用 1-4 个占位符，毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
// 例子：
// (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
// (new Date()).Format("yyyy-M-d h:m:s.S")      ==> 2006-7-2 8:9:4.18
Date.prototype.Format = function (fmt) { //author: meizz
	var o = {
		"M+": this.getMonth() + 1,                 //月份
		"d+": this.getDate(),                    //日
		"h+": this.getHours(),                   //小时
		"m+": this.getMinutes(),                 //分
		"s+": this.getSeconds(),                 //秒
		"q+": Math.floor((this.getMonth() + 3) / 3), //季度
		"S": this.getMilliseconds()             //毫秒
	};
	if (/(y+)/.test(fmt))
		fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
	for (var k in o)
		if (new RegExp("(" + k + ")").test(fmt))
			fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
	return fmt;
}

const tiPost = (url, data, contentType, cookie, referer, proxy) => {
	return new Promise((resolve, reject) => {
		superagent.post(url).timeout(30000)
			.set('Host', 'www.ti.com.cn')
			.set('Connection', 'keep-alive')
			.set('sec-ch-ua', '"Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"')
			.set('sec-ch-ua-mobile', '?0')
			.set('user-agent','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36')
			.set('Content-Type', contentType)
			.set('X-Sec-Clge-Req-Type', 'ajax')
			.set('Expires', '0')
			.set('Cache-Control', 'no-store, must-revalidate')
			.set('sec-ch-ua-platform', '"macOS"')
			.set('Accept', '*/*')
			.set('Origin', 'https://www.ti.com.cn')
			.set('Sec-Fetch-Site', 'same-origin')
			.set('Sec-Fetch-Mode', 'cors')
			.set('Sec-Fetch-Dest', 'empty')
			.set('Referer', referer)
			.set('Accept-Encoding', 'gzip, deflate, br')
			.set('Accept-Language', 'zh-CN,zh;q=0.9,en;q=0.8')
			.set('Cookie', cookie)
			.send(data)
			.end((err, res) => {
				if (err) {
					return reject(err);
				}
				resolve(res.text);
			});
	});
}

const tiGet = (url, cookie, referer, proxy, opt) => {
	return new Promise((resolve, reject) => {
		superagent.get(url).timeout(30000)
			.set('Host', 'www.ti.com.cn')
			.set('Connection', 'keep-alive')
			.set('sec-ch-ua', '"Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"')
			.set('sec-ch-ua-mobile', '?0')
			.set('user-agent','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36')
			.set('sec-ch-ua-platform', '"macOS"')
			.set('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9')
			.set('Referer', referer)
            .set('Sec-Fetch-Dest', 'document')
            .set('Sec-Fetch-Mode', 'navigate')
            .set('Sec-Fetch-Site', opt['Sec-Fetch-Site'] || 'none')
            .set('Sec-Fetch-User', '?1')
            .set('Upgrade-Insecure-Requests', '1')
			.set('Accept-Encoding', 'gzip, deflate, br')
			.set('Accept-Language', 'zh-CN,zh;q=0.9,en;q=0.8')
			.set('Cookie', cookie)
			.end((err, res) => {
				if (err) {
					return reject(err);
				}
				resolve(res.text);
			});
	});
}

const getProxy = () => {
	return new Promise((resolve, reject) => {
		const proxySvr = 'http://tiqu.linksocket.com:81/abroad?num=1&type=1&lb=1&sb=0&flow=1&regions=us1&port=1';
		superagent.get(proxySvr).timeout(10000)
			.set('user-agent','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36')
			.end((err, res) => {
				if (err) {
					return reject(err);
				}
				const proxy = 'http://'+res.text;
				resolve(proxy);
			});
	});
}

const httpGet = url => {
	return new Promise((resolve, reject) => {
		superagent.get(url).timeout(30000)
			.set('user-agent','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36')
			.end((err, res) => {
				if (err) {
					return reject(err);
				}
				resolve({
                    body: res.text,
                    setCookie: res.headers['set-cookie'],
                });
			});
	});
}

let g_cookie = '';

const getTiCookieByName = name => {
    const reg = new RegExp(name+'=([^;]+);');
    const result = g_cookie.match(reg);
    return result[1] ? result[1] : '';
}

const getTiCookie = replacement => {
    if (replacement) {
        for (const k in replacement) {
            if (g_cookie.indexOf(k+'=') > -1) {
                g_cookie = g_cookie.replace(new RegExp(k+'=[^;]+;'), k+'='+replacement[k]+';');
            } else {
                g_cookie = k + '=' + replacement[k] + '; ' + g_cookie;
            }
        }
        //写回覆盖
        fs.writeFile('cookie.txt', g_cookie, () => {});
    }
    return g_cookie;
}

const readCookieFromFile = () => {
    return new Promise((resolve, reject) => {
        fs.readFile('cookie.txt', 'utf-8', (err, data) => {
            if (err) {
                reject(err);
            } else {
                if (data.indexOf('Cookie:') === 0) {
                    data = data.substr(7).trim();
                }
                resolve(data);
            }
        });
    });
}


(async () => {
    //读cookie
    g_cookie = await readCookieFromFile();

    
    let serial;

     serial = 'LMH3401IRMST';

    let ti_geo;
    let ti_ua;
    let ret;//请求返回
    let html;//返回的html
    let url;//请求地址
    let data;//请求包
    let referer;
    let cookie = getTiCookie();
    let retJson;//返回的json数据
    let cartId;//购物车id
    let stock;//库存数
    let tmp;//临时变量
    let CSRFToken;//CSRFToken
    let proxy;//代理

    // try {
    //     logger('获取代理');
    //     proxy = await getProxy();
    // } catch(e) {
    //     logger('获取代理失败');
    //     
    // }

    logger(serial, '获取商品库存数量');
    url = 'https://www.ti.com.cn/storeservices/cart/opninventory?opn='+encodeURIComponent(serial);
    try {
        ret = await httpGet(url);
        if (ret.setCookie) {
            for (const str of ret.setCookie) {
                const kv = str.split(';')[0];
                const key = kv.substr(0, kv.indexOf('='));
                const value = kv.substr(kv.indexOf('=')+1);
    
                if (key == 'ti_geo') {
                    ti_geo = value;
                    logger('ti_geo', ti_geo);
                } else if (key == 'ti_ua') {
                    ti_ua = value;
                    logger('ti_ua', ti_ua);
                }
            }

            //将geo和ua信息更新到cookie，避免被识别为机器人
            cookie = getTiCookie({
                //ti_geo, ti_ua,
            });
        } else {
            logger('返回内容异常');
            await sleep(10000);
            
        }

        const res = JSON.parse(ret.body);
        stock = res.inventory;
        logger(serial, '库存数', stock);
        await sleep(2000);
    } catch(e) {
        logger('获取商品库存失败', e);
        await sleep(2000);
        
    }
    //debug
    // stock = 10;



    logger('加购物车');
    const stepAddCart = async () => {
        url = 'https://www.ti.com.cn/occservices/v2/ti/addtocart';
        data = JSON.stringify({
            'cartRequestList':[
                {
                    'opnId':serial,
                    'quantity':stock,
                    'packageOption':null,
                    'tiAddtoCartSource':'ti.com-quickcart',
                }
            ],
            currency:'CNY',
        });
        referer = 'https://www.ti.com.cn/store/ti/zh/p/product/?p='+encodeURIComponent(serial);
        //referer = 'https://www.ti.com.cn/ordering-resources/buying-tools/quick-add-to-cart.html';
        try {
            ret = await tiPost(url, data, 'application/json', cookie, referer, proxy);
            retJson = JSON.parse(ret);
            if (retJson.statusCode && retJson.statusCode == '200' && retJson.cartId) {
                cartId = retJson.cartId;
                logger('加购物车成功，购物车ID', cartId);

                //设置cookie里的购物车ID
                cookie = getTiCookie({
                    'ti-cart': cartId,
                });
            } else {
                logger('加购物车返回异常');
                //todo:发送短信
                await sleep(5000);
                return false;
            }
        } catch(e) {
            logger('加购物车失败', e);
            await sleep(5000);
            return false;
        }
        return true;
    }
    if (!await stepAddCart() && !await stepAddCart()) {
        await sleep(60000);
        
    }



    //获取 CSRFToken
    logger('获取 CSRFToken');
    const stepGetCSRFToken = async () => {
        const _ticdt = new Buffer(parseInt(new Date().getTime().toString().slice(0, -3)) + '|' + getTiCookieByName('tiSessionID') + '|' + getTiCookieByName('_ga'), 'binary').toString('base64');
        url = 'https://www.ti.com.cn/store/ti/zh/cart?contShopUrl=https%3A%2F%2Fwww.ti.com.cn%2F%3Flogin-check%3Dtrue&_ticdt='+_ticdt;
        referer = 'https://www.ti.com.cn/';
        try {
            html = await tiGet(url, cookie, referer, proxy, {'Sec-Fetch-Site':'cross-site'});
            tmp = html.match(/ACC.config.CSRFToken[ \t]{0,}=[ \t]{0,}"([0-9a-zA-Z-]{5,})"/);
            if (tmp[1]) {
                CSRFToken = tmp[1];
                logger('CSRFToken', CSRFToken);
            } else {
                logger('获取 CSRFToken 异常');
                await sleep(10000);
                return false;
            }
        } catch(e) {
            logger('获取 CSRFToken 失败', e);
            await sleep(10000);
            return false;
        }
        return true;
    }
    if (!await stepGetCSRFToken() && !await stepGetCSRFToken()) {
        await sleep(60000);
        
    }



    logger('提交地址');
    const stepAddSelected = async () => {
        url = 'https://www.ti.com.cn/store/ti/zh/checkout/buy/multi/delivery-address/addSelected';
        referer = 'https://www.ti.com.cn/store/ti/zh/checkout/buy/multi/delivery-address/add?storeFlashAtts=true&validPrice=true';
        data = 'addressType=Business&countryIso=CN&editAddress=true&addressId=9015785586711&shippingAddress=true&firstName=Xiaochong&lastName=Zhang&line1=576%2C+5+%2F+F%2C+phase+I%2C+Huaqiang+North&line2=New+Asia%2C+Futian+District&townCity=Shenzhen+City&state=Guangdong+Province&gstn=&panNumber=&sezCustomer=&postcode=518000&companyName=chuangxinrun+Electronics+Co.%2C+Ltd&companyUrl=http%3A%2F%2Fzxiaocong.hqew.com%2F&gstExemptCert=&pstExemptCert=&qstExemptCert=&taxId=&phoneCountryPrefix=86-CN&phoneNumber=136+3267+1185&phoneExtension=&email=cxr228%40chuangxinrun.com&_saveInAddressBook=on&middleName2=Shenzhen&taxExemptValidated=false&isTaxExempt=false&same_billingAddress=on&billingAddress=true&CSRFToken='+CSRFToken;
        try {
            ret = await tiPost(url, data, 'application/x-www-form-urlencoded; charset=UTF-8', cookie, referer, proxy);
            retJson = JSON.parse(ret);
            if (!retJson.validated) {
                logger('提交地址返回不正确');
                await sleep(10000);
                return false;
            } else {
                logger('提交地址成功');
            }
        } catch(e) {
            logger('提交地址失败', e);
            await sleep(10000);
            return false;
        }
        return true;
    }
    if (!await stepAddSelected() && !await stepAddSelected() && !await stepAddSelected()) {
        await sleep(60000);
        
    }



    logger('确认税单');
    const stepTaxInvoice = async () => {
        url = 'https://www.ti.com.cn/store/ti/zh/checkout/multi/cn-tax-invoice/add';
        data = 'id=&type=SPECIALPAPERINVOICE&recipient=%E6%B7%B1%E5%9C%B3%E5%B8%82%E5%88%9B%E6%96%B0%E6%B6%A6%E7%94%B5%E5%AD%90%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8&vatInvoiceTitleFlag=true&taxRegistrationNumber=91440300359713066T&registrationAddress=%E6%B7%B1%E5%9C%B3%E5%B8%82%E7%A6%8F%E7%94%B0%E5%8C%BA%E5%8D%8E%E5%BC%BA%E5%8C%97%E8%A1%97%E9%81%93%E4%B8%AD%E8%88%AA%E8%B7%AF%E6%96%B0%E4%BA%9A%E6%B4%B2%E4%B8%80%E6%9C%9F5%E6%A5%BC576&phoneNumber=075+5825+44500&bankName=%E4%B8%AD%E5%9B%BD%E6%B0%91%E7%94%9F%E9%93%B6%E8%A1%8C%E5%8D%8E%E5%BC%BA%E6%94%AF%E8%A1%8C&bankAccountNo=150066364&vatInvoiceAddress.firstName=%E5%BC%A0%E6%99%93%E5%86%B2&vatInvoiceAddress.companyName=%E6%B7%B1%E5%9C%B3%E5%B8%82%E5%88%9B%E6%96%B0%E6%B6%A6%E7%94%B5%E5%AD%90%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8&vatInvoiceAddress.phoneCountryPrefix=0&vatInvoiceAddress.phoneNumber=136+3267+1185&billTo_countryIso=0&vatInvoiceAddress.countryIso=CN&vatInvoiceAddress.line1=%E6%B7%B1%E5%9C%B3%E5%B8%82%E7%A6%8F%E7%94%B0%E5%8C%BA%E5%8D%8E%E5%BC%BA%E5%8C%97%E8%A1%97%E9%81%93%E4%B8%AD%E8%88%AA%E8%B7%AF%E6%96%B0%E4%BA%9A%E6%B4%B2%E4%B8%80%E6%9C%9F5%E6%A5%BC576&vatInvoiceAddress.townCity=%E6%B7%B1%E5%9C%B3%E5%B8%82&vatInvoiceAddress.state=%E5%B9%BF%E4%B8%9C%E7%9C%81&vatInvoiceAddress.postcode=518000&phone1=0&mobileNumber=&email=&CSRFToken='+CSRFToken;
        referer = 'https://www.ti.com.cn/store/ti/zh/checkout/multi/cn-tax-invoice';
        try {
            ret = await tiPost(url, data, 'application/x-www-form-urlencoded; charset=UTF-8', cookie, referer, proxy);
            if (ret.indexOf('ACC.config.CSRFToken') < 0) {
                logger('确认税单异常');
                await sleep(10000);
                return false;
            } else {
                logger('确认税单成功');
            }
        } catch(e) {
            logger('确认税单失败', e);
            await sleep(10000);
            return false;
        }
        return true;
    }
    if (!await stepTaxInvoice() && !await stepTaxInvoice()) {
        await sleep(60000);
        
    }



    logger('合规确认');
    const stepRegulations = async () => {
        referer = 'https://www.ti.com.cn/store/ti/zh/checkout/buy/multi/regulations-step/choose';
        url = 'https://www.ti.com.cn/store/ti/zh/checkout/buy/multi/regulations-step/validate?militaryFlag=No&eeId=22565&eeName=%E6%B8%B8%E6%88%8F%E6%8E%A7%E5%88%B6%E5%99%A8%E5%92%8C%E5%A4%96%E8%AE%BE&appId=162&appName=%E6%B8%B8%E6%88%8F&selectedIOR=';
        try {
            ret = await tiGet(url, cookie, referer, proxy, {'Sec-Fetch-Site':'same-origin'});
            if (ret.indexOf('ACC.config.CSRFToken') < 0) {
                logger('合规确认失败');
                await sleep(10000);
                return false;
            } else {
                logger('合规确认成功');
            }
        } catch(e) {
            logger('合规确认失败', e);
            await sleep(10000);
            return false;
        }
        return true;
    }
    if (!await stepRegulations() && !await stepRegulations()) {
        await sleep(60000);
        
    }



    logger('运费确认');
    const stepDelivery = async () => {
        referer = 'https://www.ti.com.cn/store/ti/zh/checkout/buy/multi/delivery-method/choose';
        url = 'https://www.ti.com.cn/store/ti/zh/checkout/buy/multi/delivery-method/select?delivery_method=v2-china-INT-0_1k-EH&termsAccepted=Yes';
        try {
            ret = await tiGet(url, cookie, referer, proxy, {'Sec-Fetch-Site':'same-origin'});
            if (ret.indexOf('ACC.config.CSRFToken') < 0) {
                logger('运费确认失败');
                await sleep(10000);
                return false;
            } else {
                logger('运费确认成功');
            }
        } catch(e) {
            logger('运费确认失败', e);
            await sleep(10000);
            return false;
        }
        return true;
    }
    if (!await stepDelivery() && !await stepDelivery()) {
        await sleep(60000);
        
    }



    logger('提交订单');
    const stepPayment = async () => {
        data = 'paymentMethod=unionpay_b&CSRFToken='+CSRFToken;
        referer = 'https://www.ti.com.cn/store/ti/zh/checkout/buy/multi/payment-method/add';
        url = 'https://www.ti.com.cn/store/ti/zh/checkout/buy/multi/payment-method/citcon/addSelectedPayment';
        try {
            html = await tiPost(url, data, 'application/x-www-form-urlencoded; charset=UTF-8', cookie, referer, proxy);
            logger('html', html);
            const tmp = html.match(/T\d{6,9}/);
            if (tmp && tmp[0]) {
                const orderId = tmp[0];
                //todo:发送短信
                logger('提交订单成功！', orderId);
            } else {
                logger('提交订单失败');
                await sleep(10000);
                return false;
            }
        } catch(e) {
            logger('提交订单失败', e);
            await sleep(10000);
            return false;
        }
        return true;
    }
    if (!await stepPayment() && !await stepPayment()) {
        await sleep(60000);
        
    }

    await sleep(60000);

})();
